package com.stephentuso.welcome;

import ohos.aafwk.ability.fraction.FractionAbility;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.PageSlider;
import ohos.agp.components.PageSliderProvider;
import ohos.agp.components.StackLayout;
import ohos.agp.window.service.WindowManager;

public abstract class WelcomeAbility extends FractionAbility {

    public static final String WELCOME_SCREEN_KEY = "welcome_screen_key";

    protected PageSlider viewPager;
    private WelcomePageViewPagerAdapter adapter;
    private WelcomeConfiguration configuration;
    private WelcomeItemList responsiveItems = new WelcomeItemList();

    @Override
    protected void onStart(Intent intent) {
        configuration = configuration();
        super.onStart(intent);
        getWindow().addFlags(WindowManager.LayoutConfig.MARK_TRANSLUCENT_STATUS);
        setUIContent(ResourceTable.Layout_wel_ability_welcome);

        adapter = new WelcomePageViewPagerAdapter();

        viewPager = (PageSlider) findComponentById(ResourceTable.Id_wel_view_pager);
        viewPager.setOrientation(Component.HORIZONTAL);
        viewPager.setSlidingPossible(true);
        viewPager.setProvider(adapter);

        responsiveItems = new WelcomeItemList();

        // -- Inflate the bottom layout -- //

        StackLayout bottomFrame = (StackLayout) findComponentById(ResourceTable.Id_wel_bottom_frame);
        LayoutScatter.getInstance(this).parse(configuration.getBottomLayoutResId(), bottomFrame, true);

        // -- Add buttons to responsiveItems -- //
        // addViewWrapper() will filter out any that aren't in the current layout

        SkipButton skip = new SkipButton(findComponentById(ResourceTable.Id_wel_button_skip));
        addViewWrapper(skip, new Component.ClickedListener() {
            @Override
            public void onClick(Component v) {
                completeWelcomeScreen();
            }
        });

        PreviousButton prev = new PreviousButton(findComponentById(ResourceTable.Id_wel_button_prev));
        addViewWrapper(prev, new Component.ClickedListener() {
            @Override
            public void onClick(Component v) {
                scrollToPreviousPage();
            }
        });

        NextButton next = new NextButton(findComponentById(ResourceTable.Id_wel_button_next));
        addViewWrapper(next, new Component.ClickedListener() {
            @Override
            public void onClick(Component v) {
                scrollToNextPage();
            }
        });

        DoneButton done = new DoneButton(findComponentById(ResourceTable.Id_wel_button_done));
        addViewWrapper(done, new Component.ClickedListener() {
            @Override
            public void onClick(Component v) {
                completeWelcomeScreen();
            }
        });

        Component firstBarButton = findComponentById(ResourceTable.Id_wel_button_bar_first);
        if (firstBarButton != null) {
            firstBarButton.setClickedListener(new Component.ClickedListener() {
                @Override
                public void onClick(Component v) {
                    onButtonBarFirstPressed();
                }
            });
        }

        Component secondBarButton = findComponentById(ResourceTable.Id_wel_button_bar_second);
        if (secondBarButton != null) {
            secondBarButton.setClickedListener(new Component.ClickedListener() {
                @Override
                public void onClick(Component v) {
                    onButtonBarSecondPressed();
                }
            });
        }

        WelcomeViewPagerIndicator indicator = (WelcomeViewPagerIndicator) findComponentById(ResourceTable.Id_wel_pager_indicator);
        if (indicator != null) {
            responsiveItems.add(indicator);
        }

        WelcomeBackgroundView background = (WelcomeBackgroundView) findComponentById(ResourceTable.Id_wel_background_view);

        WelcomeViewHider hider = new WelcomeViewHider(findComponentById(ResourceTable.Id_wel_root));
        hider.setOnViewHiddenListener(new WelcomeViewHider.OnViewHiddenListener() {
            @Override
            public void onViewHidden() {
                completeWelcomeScreen();
            }
        });

        responsiveItems.addAll(background, hider, configuration.getPages());

        responsiveItems.setup(configuration);

        viewPager.addPageChangedListener(responsiveItems);
        viewPager.setCurrentPage(configuration.firstPageIndex());

        responsiveItems.onPageChosen(viewPager.getCurrentPage());
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (viewPager != null) {
            viewPager.removePageChangedListener(responsiveItems);
        }
    }

    /**
     * Helper method to add button to list,
     * checks for null first
     *
     * @param wrapper view wrapper
     * @param onClickListener click event listener
     */
    private void addViewWrapper(WelcomeViewWrapper wrapper, Component.ClickedListener onClickListener) {
        if (wrapper.getView() != null) {
            wrapper.setOnClickListener(onClickListener);
            responsiveItems.add(wrapper);
        }
    }

    /* package */ boolean scrollToNextPage() {
        if (!canScrollToNextPage()) {
            return false;
        }
        viewPager.setCurrentPage(getNextPageIndex());
        return true;
    }

    /* package */ boolean scrollToPreviousPage() {
        if (!canScrollToPreviousPage()) {
            return false;
        }
        viewPager.setCurrentPage(getPreviousPageIndex());
        return true;
    }

    protected int getNextPageIndex() {
        return viewPager.getCurrentPage() + (configuration.isRtl() ? -1 : 1);
    }

    protected int getPreviousPageIndex() {
        return viewPager.getCurrentPage() + (configuration.isRtl() ? 1 : -1);
    }

    protected boolean canScrollToNextPage() {
        return configuration.isRtl() ? getNextPageIndex() >= configuration.lastViewablePageIndex() : getNextPageIndex() <= configuration.lastViewablePageIndex();
    }

    protected boolean canScrollToPreviousPage() {
        return configuration.isRtl() ? getPreviousPageIndex() <= configuration.firstPageIndex() : getPreviousPageIndex() >= configuration.firstPageIndex();
    }

    /**
     * Called when the first (left in LTR layout direction) button
     * is pressed when using the button bar bottom layout
     */
    protected void onButtonBarFirstPressed() {

    }

    /**
     * Called when the second (right in LTR layout direction) button
     * is pressed when using the button bar bottom layout
     */
    protected void onButtonBarSecondPressed() {

    }

    /**
     * Closes the ability and saves it as completed.
     * A subsequent call to WelcomeScreenHelper.show() would not show this again,
     * unless the key is changed.
     */
    protected void completeWelcomeScreen() {
        WelcomeSharedPreferencesHelper.storeWelcomeCompleted(this, getKey());
        setWelcomeScreenResult(-1);
        terminateAbility();
        if (configuration.getExitAnimation() != WelcomeConfiguration.NO_ANIMATION_SET)
            setTransitionAnimation(ResourceTable.Animation_wel_none, configuration.getExitAnimation());
    }

    /**
     * Closes the ability, doesn't save as completed.
     * A subsequent call to WelcomeScreenHelper.show() would show this again.
     */
    protected void cancelWelcomeScreen() {
        setWelcomeScreenResult(0);
        terminateAbility();
    }

    @Override
    public void onBackPressed() {
        // Scroll to previous page and return if back button navigates
        if (configuration.getBackButtonNavigatesPages() && scrollToPreviousPage()) {
            return;
        }

        if (configuration.getCanSkip() && configuration.getBackButtonSkips()) {
            completeWelcomeScreen();
        } else {
            cancelWelcomeScreen();
        }

    }

    private void setWelcomeScreenResult(int resultCode) {
        Intent intent = this.getIntent();
        intent.setParam(WELCOME_SCREEN_KEY, getKey());
        this.setResult(resultCode, intent);
    }

    private String getKey() {
        return WelcomeUtils.getKey(this.getClass());
    }

    protected abstract WelcomeConfiguration configuration();

    private class WelcomePageViewPagerAdapter extends PageSliderProvider {

        @Override
        public Object createPageInContainer(ComponentContainer componentContainer, int i) {
            ComponentContainer component = configuration.createPageView(i);
            componentContainer.addComponent(component);
            return component;
        }

        @Override
        public void destroyPageFromContainer(ComponentContainer componentContainer, int i, Object o) {
            if (componentContainer != null) {
                if (o instanceof Component) {
                    componentContainer.removeComponent((Component) o);
                }
            }
        }

        @Override
        public boolean isPageMatchToObject(Component component, Object o) {
            return true;
        }

        @Override
        public int getCount() {
            return configuration.pageCount();
        }
    }
}
